#include <stdio.h>

void f(int a)
{
	switch(a) {
		case 0: printf("zero\n");
				break;
		case 1: printf("one\n");
				break;
		case 2: printf("two\n");
				break;
		default: printf("something unknown\n"); 
				 break;
	}
}

int main()
{
	f(2);
}

#if 0

如果仅从汇编代码入手，无法判断上述函数是一个判断表达式较少的switch()语句、还是一组if语句。
确实可以认为，switch()语句是一种旨在简化大量嵌套if()语句设计的语法。

mov eax, [esp-4]
sub exa, 0
这两条指令可以检查EAX的值是否是零。如果EAX的值是零，ZF会被置1(也就是说0-0=1，这就可以提前设置ZF标志位)，并会触发第一条条件转移
指令JE。如果EAX的值仍然不是零，则不会触发第一条转移指令。
做"eax=eax-1"的运算，若计算结果是零则做相应输出。

在把字符串指针存储到变量a之后，函数使用JMP调用printf。在调用printf函数的时候，调用方函数而没有使用常规的call指令。
这点不难释：调用方函数把参数推送入栈之后，的确通常通过CALL指令调用其他函数。这种情况下，CALL会把返回地址推送入栈、并通过
无条件转移的手段启用被调用方函数。

#endif

#if 0
/*
 * intel
 */
0000000000001149 <f>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	48 83 ec 10          	sub    $0x10,%rsp		// rsp=rsp-0x10
    1155:	89 7d fc             	mov    %edi,-0x4(%rbp)	// parameter=a
    1158:	83 7d fc 02          	cmpl   $0x2,-0x4(%rbp)	// a-2
    115c:	74 30                	je     118e <f+0x45>	// 2-2=0, zf=1, jump
    115e:	83 7d fc 02          	cmpl   $0x2,-0x4(%rbp)	// a-2
    1162:	7f 38                	jg     119c <f+0x53>	// ((SF xor OF) or ZF) = 0, jump
    1164:	83 7d fc 00          	cmpl   $0x0,-0x4(%rbp)	// a-0
    1168:	74 08                	je     1172 <f+0x29>	// 0-0=0, zf=1, jump, 
    116a:	83 7d fc 01          	cmpl   $0x1,-0x4(%rbp)	// a-1
    116e:	74 10                	je     1180 <f+0x37>	// 1-1=0, zf=1, jump
    1170:	eb 2a                	jmp    119c <f+0x53>
    1172:	48 8d 3d 8b 0e 00 00 	lea    0xe8b(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1179:	e8 d2 fe ff ff       	callq  1050 <puts@plt>
    117e:	eb 29                	jmp    11a9 <f+0x60>	// break
    1180:	48 8d 3d 82 0e 00 00 	lea    0xe82(%rip),%rdi        # 2009 <_IO_stdin_used+0x9>
    1187:	e8 c4 fe ff ff       	callq  1050 <puts@plt>
    118c:	eb 1b                	jmp    11a9 <f+0x60>
    118e:	48 8d 3d 78 0e 00 00 	lea    0xe78(%rip),%rdi        # 200d <_IO_stdin_used+0xd>
    1195:	e8 b6 fe ff ff       	callq  1050 <puts@plt>
    119a:	eb 0d                	jmp    11a9 <f+0x60>
    119c:	48 8d 3d 6e 0e 00 00 	lea    0xe6e(%rip),%rdi        # 2011 <_IO_stdin_used+0x11>
    11a3:	e8 a8 fe ff ff       	callq  1050 <puts@plt>
    11a8:	90                   	nop
    11a9:	90                   	nop
    11aa:	c9                   	leaveq 
    11ab:	c3                   	retq   

00000000000011ac <main>:
    11ac:	f3 0f 1e fa          	endbr64 
    11b0:	55                   	push   %rbp
    11b1:	48 89 e5             	mov    %rsp,%rbp
    11b4:	bf 02 00 00 00       	mov    $0x2,%edi
    11b9:	e8 8b ff ff ff       	callq  1149 <f>
    11be:	b8 00 00 00 00       	mov    $0x0,%eax
    11c3:	5d                   	pop    %rbp
    11c4:	c3                   	retq   
    11c5:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    11cc:	00 00 00 
    11cf:	90                   	nop

/*
 * arm
 */
000000000040055c <f>:
  40055c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400560:	910003fd 	mov	x29, sp
  400564:	b9001fa0 	str	w0, [x29, #28]
  400568:	b9401fa0 	ldr	w0, [x29, #28]
  40056c:	7100041f 	cmp	w0, #0x1			// 1
  400570:	54000120 	b.eq	400594 <f+0x38>  // b.none
  400574:	7100081f 	cmp	w0, #0x2			// 2
  400578:	54000160 	b.eq	4005a4 <f+0x48>  // b.none
  40057c:	7100001f 	cmp	w0, #0x0
  400580:	540001a1 	b.ne	4005b4 <f+0x58>  // b.any
  400584:	90000000 	adrp	x0, 400000 <_init-0x3e8>	// =0
  400588:	911a8000 	add	x0, x0, #0x6a0
  40058c:	97ffffb1 	bl	400450 <puts@plt>
  400590:	1400000d 	b	4005c4 <f+0x68>				// break;
  400594:	90000000 	adrp	x0, 400000 <_init-0x3e8>	// =1
  400598:	911aa000 	add	x0, x0, #0x6a8
  40059c:	97ffffad 	bl	400450 <puts@plt>
  4005a0:	14000009 	b	4005c4 <f+0x68>
  4005a4:	90000000 	adrp	x0, 400000 <_init-0x3e8>	// =2
  4005a8:	911ac000 	add	x0, x0, #0x6b0
  4005ac:	97ffffa9 	bl	400450 <puts@plt>
  4005b0:	14000005 	b	4005c4 <f+0x68>
  4005b4:	90000000 	adrp	x0, 400000 <_init-0x3e8>	// !=0
  4005b8:	911ae000 	add	x0, x0, #0x6b8
  4005bc:	97ffffa5 	bl	400450 <puts@plt>
  4005c0:	d503201f 	nop
  4005c4:	d503201f 	nop
  4005c8:	a8c27bfd 	ldp	x29, x30, [sp], #32
  4005cc:	d65f03c0 	ret

00000000004005d0 <main>:
  4005d0:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  4005d4:	910003fd 	mov	x29, sp
  4005d8:	52800040 	mov	w0, #0x2                   	// #2
  4005dc:	97ffffe0 	bl	40055c <f>
  4005e0:	52800000 	mov	w0, #0x0                   	// #0
  4005e4:	a8c17bfd 	ldp	x29, x30, [sp], #16
  4005e8:	d65f03c0 	ret
  4005ec:	00000000 	.inst	0x00000000 ; undefined


#endif

